package com.alibaba.citrus.ots.application.report.ability.facade.service;

import com.alibaba.citrus.ots.application.report.ability.repository.BaseDataQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.utils.DomUtil;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIds2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByIds2Response;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Response;
import com.epoch.app.bcorder.model.dto.ListPlatformPageReportRequest;
import com.epoch.app.bcorder.model.dto.ListPlatformPageReportResponse;
import com.epoch.app.bcorder.model.dto.OrganizationSDO;
import com.epoch.app.bcorder.model.dto.SearchWarehouseForPlatformNewRequest;
import com.epoch.app.bcorder.model.dto.SearchWarehouseForPlatformNewResponse;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crunifiedinventory.model.dto.OuiWareshouseIndexRequest;
import com.epoch.app.crunifiedinventory.model.enums.AllocateOrderStatus;
import com.epoch.app.crunifiedinventory.ouiwarehouse.model.OuiWarehouse;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import com.epoch.app.otsapplicationreportsdk.commercustomerplanreport.dto.FullPlatformCustomerGroupRequest;
import com.epoch.app.otsapplicationreportsdk.commercustomerplanreport.dto.FullPlatformCustomerGroupResponse;
import com.epoch.app.otsapplicationreportsdk.commercustomerplanreport.model.CommerCustomerPlanReport;
import com.epoch.app.otsapplicationreportsdk.commercustomerplanreport.service.CommerCustomerPlanReportService;
import com.epoch.app.otsapplicationreportsdk.contants.OtsApplicationReportSdkConstants;
import com.epoch.app.otsapplicationreportsdk.ecinventorystats.dto.QueryByCustomerList2Request;
import com.epoch.app.otsapplicationreportsdk.ecinventorystats.dto.QueryByCustomerListReadOnlyRequest;
import com.epoch.app.otsapplicationreportsdk.ecinventorystats.model.EcInventoryStats;
import com.epoch.app.otsapplicationreportsdk.ecinventorystats.service.EcInventoryStatsService;
import com.epoch.app.otsapplicationreportsdk.fullchaininventory.model.FullChainInventory;
import com.epoch.app.otsapplicationreportsdk.fullchaininventoryreport.dto.FullChainInventoryLoadForPageRequest;
import com.epoch.app.otsapplicationreportsdk.fullchaininventoryreport.service.FullChainInventoryReportService;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftob.dto.QueryAllocateOrderDetailReportFtobRequest;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftob.model.OarsAllocateOrderDetailReportFtob;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftob.service.OarsAllocateOrderDetailReportFtobService;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftof1.dto.QueryAllocateOrderDetailReportFtof1Request;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftof1.model.OarsAllocateOrderDetailReportFtof1;
import com.epoch.app.otsapplicationreportsdk.oarsallocateorderdetailreportftof1.service.OarsAllocateOrderDetailReportFtof1Service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 电商_全链条库存&周转报表 查询
 */
@Primary
@Component
public class FullChainInventoryReportServiceImpl implements FullChainInventoryReportService {

    private static Log log = Log.getLogger(FullChainInventoryReportServiceImpl.class);

    @Resource
    OarsAllocateOrderDetailReportFtof1Service oarsAllocateOrderDetailReportFtof1Service;

    @Resource
    EcInventoryStatsService ecInventoryStatsService;

    @Resource
    BaseDataService baseDataService;

    @Resource
    CommerCustomerPlanReportService commerCustomerPlanReportService;

    @Resource
    private BcOrderService bcOtsService;

    @Resource
    private CrUnifiedInventoryService otsUnifiedInventoryService;

    @Resource(name="allocateApplyOrderTaskExecutor")
    ThreadPoolTaskExecutor allocateApplyOrderTaskExecutor;

    @Resource
    OarsAllocateOrderDetailReportFtobService oarsAllocateOrderDetailReportFtobService;

    @Resource
    BaseDataQueryRepository baseDataQueryRepository;

    @Override
    @FacadeInvoker
    public Result<List<FullChainInventory>> fullChainInventoryLoadForPage(FullChainInventoryLoadForPageRequest fullChainInventoryLoadForPageRequest) {
        return fullChainInventoryLoadForPageV1(fullChainInventoryLoadForPageRequest);
        //return fullChainInventoryStatLoadForPage(fullChainInventoryLoadForPageRequest);
    }

    public static void main(String[] args) {
        Date date = DateUtils.parse("2022-4-15");
        System.out.println(date);
    }

    /**
     * 全链路周转
     * @param request 入参
     * @return
     */
    private Result<List<FullChainInventory>> fullChainInventoryLoadForPageV1(FullChainInventoryLoadForPageRequest request) {
        // 默认查询当天的记录
        Date todayDate = DateUtils.parseToday(request.getTime());
        request.setTime(DateUtils.formatDate(DateUtils.getLatestTime(todayDate), DateUtils.DATETIME_FORMAT));
        // 分页获取 电商平台
        Result<List<Object>> platformPage = getPlatformPage(request);
        // 如果查询结果没有电商平台,则返回空
        if (CollectionUtils.isEmpty(platformPage.getResult())) {
            return Result.success(new ArrayList<>());
        }
        List<String> platformIds = new ArrayList<>();
        // 电商平台id：电商平台name
        Map<String, String> platformNameByCodeMap = new HashMap<>();
        platformPage.getResult().forEach(o -> {
            Map map = (Map) o;
            if (map.get("platformId") != null) {
                platformIds.add(map.get("platformId").toString());
                platformNameByCodeMap.put(map.get("platformId").toString(), map.get("platformName").toString());
            }
        });
        log.info("Step1_fullChainInventoryLoadForPage_platformIds={},platformNameByCodeMap{}",JSON.toJSONString(platformIds),JSON.toJSONString(platformNameByCodeMap));

        // 电商平台：月度计划计划量
        Map<String, List<Long>> planMonthlyMap = planMonthly(platformIds,
                DomUtil.getFirstDayDateOfMonth(DateUtils.parse(request.getTime())),
                DomUtil.getLastDayOfMonth(DateUtils.parse(request.getTime())));
        log.info("Step2_ecShareInventoryImportImpl_warehouseMap, result={}",JSONObject.toJSONString(planMonthlyMap));

        String startDate = DateUtils.formatDate(DomUtil.getFirstDayDateOfMonth(DateUtils.parse(request.getTime())));
        String endDate = DateUtils.formatDate(DateUtils.getLatestTime(todayDate));

        // 获取电商平台下的逻辑仓
        Map</*平台*/String, /*平台*/Set<String>> warehouseMap = getPlatformWarehouseMap();
        log.info("Step3_ecShareInventoryImportImpl_warehouseMap,result={}",JSONObject.toJSONString(warehouseMap));
        // 获取对应电商平台下的逻辑仓id集合
        List<String> wareHouseIds = getWareHouseIdByPlatformId(platformIds, warehouseMap);
        log.info("Step4_ecShareInventoryImportImpl_wareHouseIds,result={}",JSONObject.toJSONString(wareHouseIds));
        // 获取逻辑仓id、平台id映射集合
        Map<String, String> wareHouseIdMap = getWareHouseIdMap(platformIds, warehouseMap);
        log.info("Step5_ecShareInventoryImportImpl_wareHouseIdMap,result={}",JSONObject.toJSONString(wareHouseIdMap));

        request.setPlatformCodes(platformIds);
        // 电商平台:仓库汇总量
        Map<String, EcInventoryStats> inventoryStatsMap = inventoryStats(request);
        log.info("Step6_ecShareInventoryImportImpl_inventoryStatsMap,result={}",JSONObject.toJSONString(inventoryStatsMap));
        // 电商平台:计划调拨量
        Map<String, List<Integer>> factorySendOrderMap = getFactorySendOrder(wareHouseIds,Lists.newArrayList(startDate,endDate),wareHouseIdMap);
        log.info("Step7_ecShareInventoryImportImpl_factorySendOrderMap,result={}",JSONObject.toJSONString(factorySendOrderMap));
        // 电商平台:总部销售调拨量
        Map<String, List<Integer>> factorySalesOrderMap = getFactorySalesOrder(wareHouseIds, Lists.newArrayList(startDate, endDate), wareHouseIdMap);
        log.info("Step8_ecShareInventoryImportImpl_factorySalesOrderMap,result={}",JSONObject.toJSONString(factorySalesOrderMap));

        // 电商平台:计划调拨、总部销售调拨汇总
        // 电商平台:库存
        // Map<String, List<EcInventoryStats>> ecInventoryStatsMap = inventoryStatsByCustomer(platformIds);
        // 电商平台：电商运营部
        Map<String, String> platformBySaleChannelId = getPlatformBySaleChannelId(platformIds);
        log.info("Step9_ecShareInventoryImportImpl_platformBySaleChannelId,result={}",JSONObject.toJSONString(platformBySaleChannelId));

        // 封装页面展示参数
        List<FullChainInventory> list = new ArrayList<>();
        platformIds.forEach(platformId -> {
            FullChainInventory fullChainInventory = buildFullChainInventory(platformId, platformBySaleChannelId, platformNameByCodeMap);
            FullChainInventory chainInventory = buildFullChainInventory(fullChainInventory, inventoryStatsMap, planMonthlyMap, request, factorySendOrderMap, factorySalesOrderMap);
            list.add(chainInventory);
        });
        return Result.listSuccess(list, platformPage.getTotal());
    }

    /**
     * 分页获取 电商平台
     * @param fullChainInventoryLoadForPageRequest
     * @return
     */
    public Result<List<Object>> getPlatformPage(FullChainInventoryLoadForPageRequest fullChainInventoryLoadForPageRequest) {
        // 分页查询 电商平台
        ListPlatformPageReportRequest reportRequest = ListPlatformPageReportRequest.builder()
                .start(fullChainInventoryLoadForPageRequest.getStart())
                .limit(fullChainInventoryLoadForPageRequest.getLimit())
                .platformIds(fullChainInventoryLoadForPageRequest.getPlatformCodes())
                .build();

        // 如果查询条件没有传 电商平台 则查询所有电商平台
        List<String> allPlatFormIds = new ArrayList();
        if (CollectionUtils.isEmpty(fullChainInventoryLoadForPageRequest.getPlatformCodes())) {
//            List<String> allPlatFormIds = new ArrayList<>(platformRepository.getWarehouseByPlatFormCodes());
//            reportRequest.setPlatformIds(allPlatFormIds);
            ListPlatformPageReportRequest queryRequest = ListPlatformPageReportRequest.builder()
                    .start(0)
                    .limit(500)
                    .build();
            ListPlatformPageReportResponse response = bcOtsService.listPlatformPageReport(queryRequest);
            if (!ObjectUtils.isEmpty(response) && !CollectionUtils.isEmpty(response.getResult())) {
                response.getResult().forEach(o -> {
                    Map map = (Map) o;
                    String platformCode = (String) map.get("platformCode");
                    if (StringUtil.isNotEmpty(platformCode) && platformCode.length()>2 && "SK".equals(platformCode.substring(0,2)) && !"SK23".equals(platformCode)) {
                       allPlatFormIds.add((String)map.get("platformId"));
                    }
                });
                allPlatFormIds.add(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
            }
            reportRequest.setPlatformIds(allPlatFormIds);
        }

        // 如果 根据运营部查询需要先查询运营部下的仓库，再根据仓库关联的电商平台查询
        if (CollectionUtils.isEmpty(fullChainInventoryLoadForPageRequest.getPlatformCodes()) && !CollectionUtils.isEmpty(fullChainInventoryLoadForPageRequest.getDepartmentCodes())) {
            Set<String> platformIds = getWarehouseBySaleChannelId(fullChainInventoryLoadForPageRequest.getDepartmentCodes());
            reportRequest.setPlatformIds(new ArrayList(platformIds));
        }
        // 如果查不到任何电商平台 则返回空的
        if (CollectionUtils.isEmpty(reportRequest.getPlatformIds())) {
            return Result.listSuccess(new ArrayList<>(),0);
        }
        ListPlatformPageReportResponse listPlatformPageReportResponse = bcOtsService.listPlatformPageReport(reportRequest);
        int total = listPlatformPageReportResponse.getTotal()+1;
        List result = new ArrayList();
        if (!ObjectUtils.isEmpty(listPlatformPageReportResponse) && !CollectionUtils.isEmpty(listPlatformPageReportResponse.getResult())) {
            result = listPlatformPageReportResponse.getResult();
        }
        if (listPlatformPageReportResponse.getTotal() >= fullChainInventoryLoadForPageRequest.getStart()
                && listPlatformPageReportResponse.getTotal() <= fullChainInventoryLoadForPageRequest.getStart()+fullChainInventoryLoadForPageRequest.getLimit()) {
            // 如果查询中有其他电商平台
            if (CollectionUtils.isEmpty(reportRequest.getPlatformIds())
                    || reportRequest.getPlatformIds().contains(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())) {
                // 加上其他电商平台
                result.add(new HashMap<String, String>(){{
                    put("platformId", OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
                    put("platformName", OtsApplicationReportSdkConstants.OTHER_PLATFORM_NAME());
                }});
            }
        }
        return Result.listSuccess(result,total);
    }

    /**
     * 获取 电商运营部下（销售渠道下的） 的所有仓库 的电商平台id
     * @param saleChannelIds
     * @return
     */
    private Set<String> getWarehouseBySaleChannelId(List<String> saleChannelIds) {
        // 查询运营部下的仓库
        int start = 0;
        int limit = 500;
        OuiWareshouseIndexRequest wareshouseIndexRequest = OuiWareshouseIndexRequest.builder()
                .start(start)
                .limit(limit)
                .saleDepartments(saleChannelIds).build();
        Result<List<OuiWarehouse>> ouiWarehouseListResult = otsUnifiedInventoryService.ouiWareshouseIndex(wareshouseIndexRequest);
        if (ObjectUtils.isEmpty(ouiWarehouseListResult)) {
            log.info("查询电商下仓库为空，入参：{}", JSON.toJSONString(wareshouseIndexRequest));
            return new HashSet<>();
        }
        int allPage = (int)Math.ceil((double)ouiWarehouseListResult.getTotal() / limit);
        List<OuiWarehouse> warehouseList = ouiWarehouseListResult.getResult();
        if (CollectionUtils.isEmpty(warehouseList)) {
            log.info("查询电商下仓库为空，入参：{}", JSON.toJSONString(wareshouseIndexRequest));
            return new HashSet<>();
        }
        for (int i = 1; i < allPage; i++) {
            start = limit * i;
            wareshouseIndexRequest.setStart(start);
            Result<List<OuiWarehouse>> ouiWarehouseListResult1 = otsUnifiedInventoryService.ouiWareshouseIndex(wareshouseIndexRequest);
            if (!ObjectUtils.isEmpty(ouiWarehouseListResult1) && !CollectionUtils.isEmpty(ouiWarehouseListResult1.getResult())) {
                warehouseList.addAll(ouiWarehouseListResult1.getResult());
            }
        }

        return warehouseList.stream().filter(o->!StringUtils.isEmpty(o.getEcPlatform())).map(OuiWarehouse::getEcPlatform).collect(Collectors.toSet());
    }

    /**
     * 获取 电商平台id:电商运营部
     * @param platformIds
     * @return
     */
    private Map<String, String> getPlatformBySaleChannelId(List<String> platformIds) {
        // 查询运营部下的仓库
        int start = 0;
        int limit = 500;
        OuiWareshouseIndexRequest request = OuiWareshouseIndexRequest.builder()
                .start(start)
                .limit(limit)
                .platFormCodes(platformIds).build();
        Result<List<OuiWarehouse>> listResult = otsUnifiedInventoryService.ouiWareshouseIndex(request);
        log.info("fullChainInventoryLoadForPage_getPlatformBySaleChannelId_request={},size={}",JSONObject.toJSONString(request),listResult.getTotal());
        int allPage = (int)Math.ceil((double)listResult.getTotal() / limit);
        if (ObjectUtils.isEmpty(listResult)) {
            return new HashMap<>();
        }
        List<OuiWarehouse> warehouseList = listResult.getResult();
        if (CollectionUtils.isEmpty(warehouseList)) {
            return new HashMap<>();
        }
        for (int i = 1; i < allPage; i++) {
            start = limit * i;
            request.setStart(start);
            Result<List<OuiWarehouse>> ouiWarehouseListResult = otsUnifiedInventoryService.ouiWareshouseIndex(request);
            if (!ObjectUtils.isEmpty(ouiWarehouseListResult) && !CollectionUtils.isEmpty(ouiWarehouseListResult.getResult())) {
                warehouseList.addAll(ouiWarehouseListResult.getResult());
            }
        }

        log.info("Step9_ecShareInventoryImportImpl_warehouseList,result={}",JSONObject.toJSONString(warehouseList));
        // 销售渠道id：销售渠道名称
        Map<String, String> organizationNameById = allocateOrderByCodes(warehouseList.stream().filter(ouiWarehouse -> !StringUtils.isEmpty(ouiWarehouse.getSapSaleDepartment())).map(OuiWarehouse::getSapSaleDepartment).collect(Collectors.toList()));

        log.info("Step9_ecShareInventoryImportImpl_organizationNameById,result={}",JSONObject.toJSONString(organizationNameById));
        Map<String, String> map = new HashMap<>();
        warehouseList.forEach(ouiWarehouse -> {
            String value = map.get(ouiWarehouse.getEcPlatform());
            if (organizationNameById.get(ouiWarehouse.getSapSaleDepartment()) != null) {
                if (!StringUtils.isEmpty(value) && !Arrays.asList(value.split("/")).contains(value)) {
                    value = value + "/" + organizationNameById.get(ouiWarehouse.getSapSaleDepartment());
                } else {
                    value = organizationNameById.get(ouiWarehouse.getSapSaleDepartment());
                }
            }
            map.put(ouiWarehouse.getEcPlatform(), value);
        });

        return map;
    }


    /**
     * 获取 库存
     * @return
     */
    @FacadeInvoker
    public Map<String, List<EcInventoryStats>> inventoryStatsByCustomer(List<String> platformIds) {
        Map<String, List<EcInventoryStats>> map = new HashMap<>();
        QueryByCustomerList2Request request = new QueryByCustomerList2Request();
        request.setPlatformCodeList(platformIds);
        request.setPlatformCodeNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
        request.setStatisticalDate(DomUtil.getToday());

        Result<List<EcInventoryStats>> listResult = ecInventoryStatsService.queryByCustomerList2(request);
        log.info("fullChainInventoryLoadForPage_inventoryStatsByCustomer_request={},size={}",JSONObject.toJSONString(request),listResult.getTotal());
        if (ObjectUtils.isEmpty(listResult)) {
            return map;
        }
        List<EcInventoryStats> result = listResult.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return map;
        }

        result.forEach(stat -> {
            String platformId = StringUtils.isEmpty(stat.getPlatformCode()) ? OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID() : stat.getPlatformCode();
            List<EcInventoryStats> ecInventoryStats = map.get(platformId);
            if (CollectionUtils.isEmpty(ecInventoryStats)) {
                ecInventoryStats = new ArrayList<EcInventoryStats>(){{
                    add(stat);
                }};
            } else {
                ecInventoryStats.add(stat);
            }
            map.put(platformId, ecInventoryStats);
        });

        return map;
    }

    /**
     * 根据 code 查询 组织
     * @param code
     * @return
     */
    public OrganizationSDO allocateOrderByCode(String code) {
        BaselineGetOrganizationByOutCodes2Request request = BaselineGetOrganizationByOutCodes2Request.builder()
                .outCodes(Arrays.asList(code))
                .build();
        BaselineGetOrganizationByOutCodes2Response res = baseDataService.baselineGetOrganizationByOutCodes2(request);
        if (ObjectUtils.isEmpty(res)) {
            return null;
        }
        List<OrganizationSDO> result = res.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        return result.get(0);
    }

    /**
     * 根据 ids：组织名称
     * @param ids
     * @return
     */
    public Map<String, String> allocateOrderByCodes(List<String> ids) {
        BaselineGetOrganizationByIds2Request request = BaselineGetOrganizationByIds2Request.builder()
                .ids(ids)
                .build();
        BaselineGetOrganizationByIds2Response res = baseDataService.baselineGetOrganizationByIds2(request);
        if (ObjectUtils.isEmpty(res)) {
            return new HashMap<>();
        }
        List<OrganizationSDO> result = res.getResult();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(result)) {
            return new HashMap<>();
        }
        Map<String, String> map = new HashMap<>();
        result.forEach(sdo -> {
            map.put(sdo.getId(), sdo.getName());
        });
        return map;
    }

    /**
     * 获取 电商平台：月度计划计划量
     *
     * @param platformIds
     * @param startTime
     * @param endTime
     * @return
     */
    @FacadeInvoker
    public Map<String, List<Long>> planMonthly(List<String> platformIds, Date startTime, Date endTime) {
        List<CommerCustomerPlanReport> monthlyList = getMonthlyList(platformIds, startTime, endTime);
        log.info("FullChainInventoryReportServiceImpl.planMonthly.result={}",JSONObject.toJSONString(monthlyList));

        Map<String, List<Long>> map = new HashMap<>();
        monthlyList.forEach(monthlyCommerceSDO -> {
            // 电商平台
            String key = StringUtils.isEmpty(monthlyCommerceSDO.getPlatformCode()) ? OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID() : monthlyCommerceSDO.getPlatformCode();
            // 上旬计划任务量+上旬计划调整量
            Long fistNum = 0L;
            Long middleNum = 0L;
            Long lastNum = 0L;
            if (CollectionUtils.isEmpty(map.get(key))) {
                fistNum = monthlyCommerceSDO.getMonthFirstReviseConfirmCount();
                middleNum = monthlyCommerceSDO.getMonthMiddleReviseConfirmCount();
                lastNum = monthlyCommerceSDO.getMonthLastReviseConfirmCount();
            } else {
                List<Long> numbers = map.get(key);
                fistNum = numbers.get(0) + fistNum;
                middleNum = numbers.get(1) + middleNum;
                lastNum = numbers.get(2) + lastNum;
            }
            map.put(key, Arrays.asList(fistNum, middleNum, lastNum));
        });

        return map;
    }

    /**
     * 查询 月度计划
     *
     * @param platformIds
     * @param startTime
     * @param endTime
     * @return
     */
    @FacadeInvoker
    public List<CommerCustomerPlanReport> getMonthlyList(List<String> platformIds, Date startTime, Date endTime) {
        FullPlatformCustomerGroupRequest platformCustomerGroupRequest = new FullPlatformCustomerGroupRequest();
        int start = 0;
        int limit = 500;
        // 根据客户 批量查询
        platformCustomerGroupRequest.setPlatformCodes(platformIds);
        if (!StringUtils.isEmpty(startTime) && !StringUtils.isEmpty(endTime)) {
            platformCustomerGroupRequest.setStartTime(startTime);
            platformCustomerGroupRequest.setEndTime(endTime);
        }
        platformCustomerGroupRequest.setStart(start);
        platformCustomerGroupRequest.setLimit(limit);
        platformCustomerGroupRequest.setPlatformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
        // 查询 月度计划
        FullPlatformCustomerGroupResponse fullPlatformCustomerGroupResponse = commerCustomerPlanReportService.fullPlatformCustomerGroup(platformCustomerGroupRequest);
        log.info("fullChainInventoryLoadForPage_getMonthlyList_request={},size={}",JSONObject.toJSONString(platformCustomerGroupRequest),fullPlatformCustomerGroupResponse.getTotal());
        if (CollectionUtils.isEmpty(fullPlatformCustomerGroupResponse.getResult())) {
            return new ArrayList<>();
        }
        int allPage = fullPlatformCustomerGroupResponse.getTotal() / limit;
        if (fullPlatformCustomerGroupResponse.getTotal() % limit > 0) {
            allPage += 1;
        }
        if (ObjectUtils.isEmpty(fullPlatformCustomerGroupResponse)) {
            return new ArrayList<>();
        }
        List<CommerCustomerPlanReport> result = fullPlatformCustomerGroupResponse.getResult();
        if (ObjectUtils.isEmpty(result)) {
            return new ArrayList<>();
        }
        for (int i = 1; i < allPage; i++) {
            start = limit * i;
            platformCustomerGroupRequest.setStart(start);
            // 查询 月度计划
            FullPlatformCustomerGroupResponse response = commerCustomerPlanReportService.fullPlatformCustomerGroup(platformCustomerGroupRequest);
            if (!ObjectUtils.isEmpty(response) && !CollectionUtils.isEmpty(response.getResult())) {
                result.addAll(response.getResult());
            }
        };

        return result;
    }

    /**
     * 获取 平台code：平台id
     * @param platformIds
     * @return
     */
    public Map<String, String> platformCodeByIdMap(List<String> platformIds) {
        int start = 0;
        int limit = 100;
        // 分页查询 电商平台
        ListPlatformPageReportRequest reportRequest = ListPlatformPageReportRequest.builder()
                .start(start)
                .limit(limit)
                .platformIds(platformIds)
                .build();
        ListPlatformPageReportResponse listPlatformPageReportResponse = bcOtsService.listPlatformPageReport(reportRequest);
        int allPage = listPlatformPageReportResponse.getTotal() / limit;
        if (listPlatformPageReportResponse.getTotal() % limit > 0) {
            allPage += 1;
        }
        if (ObjectUtils.isEmpty(listPlatformPageReportResponse)) {
            return new HashMap<>();
        }
        List result = listPlatformPageReportResponse.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return new HashMap<>();
        }

        for (int i = 1; i < allPage; i++) {
            start = limit * i;
            ListPlatformPageReportRequest reportRequest1 = ListPlatformPageReportRequest.builder()
                    .start(start)
                    .limit(limit)
                    .platformIds(platformIds).build();
            ListPlatformPageReportResponse listPlatformPageReportResponse1 = bcOtsService.listPlatformPageReport(reportRequest1);
            if (!ObjectUtils.isEmpty(listPlatformPageReportResponse1) && !CollectionUtils.isEmpty(listPlatformPageReportResponse1.getResult())) {
                result.addAll(listPlatformPageReportResponse1.getResult());
            }
        }

        Map<String, String> map = new HashMap<>();
        result.forEach(o->{
            Map map1 = (Map) o;
            map.put(map1.get("platformCode").toString(), map1.get("platformId").toString());
        });
        return map;
    }

    /**
     * 电商平台:计划调拨量
     *
     * @param wareHouseIds 仓库id
     * @param time 时间
     * @return
     */
    @FacadeInvoker
    public Map<String, List<Integer>> getFactorySendOrder(List<String> wareHouseIds, List<String> time, Map<String, String> wareHouseIdMap) {
        // 客户:工厂直发订单数量
        Map<String, List<Integer>> map = new HashMap<>();
        // 获取计划调拨单
        List<OarsAllocateOrderDetailReportFtof1> orderDetailReportFtof1s = getAllocateOrderList(wareHouseIds, DateUtils.getFirstTime(time.get(0)), DateUtils.getLastTime(time.get(1)));
        // 获取工厂仓
        Map<String, WarehouseInfo> factoryLogicZoneMap = baseDataQueryRepository.getFactoryLogicZoneInfo();

        List<String> codeList = Lists.newArrayList();
        orderDetailReportFtof1s.forEach(ftof1 -> {
            //只统计发货仓为工厂仓的
            if(factoryLogicZoneMap.get(ftof1.getMainShipAreaId()) != null) {
                // 订单数量
                Integer quantity = StringUtils.isEmpty(ftof1.getSubQuantity()) ? 0 : new BigDecimal(ftof1.getSubQuantity()).intValue();

                // 最终该单的调拨量
                Integer finalNum = 0;
                if (ftof1.getMainReturnOrder() != 1) {
                    finalNum = quantity;
                } else {
                    //finalNum = quantity * -1;
                    //20220421按产品要求过滤退单数据
                    return;
                }

                Date allocateOrderCreateTime = DateUtils.string2Date(DateUtils.toDateStr(ftof1.getMainGmtCreate(), DateUtils.DATETIME_FORMAT), DateUtils.DATETIME_FORMAT);
                int fist = 0;
                int mid = 0;
                int last = 0;
                String mainReceiveAreaId = ftof1.getMainReceiveAreaId();
                String platformId = StringUtils.isEmpty(wareHouseIdMap.get(mainReceiveAreaId)) ? OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID() : wareHouseIdMap.get(mainReceiveAreaId);
                String key = wareHouseIds.contains(mainReceiveAreaId) ? platformId : OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID();
                List<Integer> value = map.get(key);
                if (value != null) {
                    fist = value.get(0);
                    mid = value.get(1);
                    last = value.get(2);
                }
                // 上旬
                if (DomUtil.earlyOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                    fist = fist + finalNum;
                }
                // 中旬
                if (DomUtil.midOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                    mid = mid + finalNum;
                }
                // 下旬
                if (DomUtil.lateOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                    last = last + finalNum;
                }
                map.put(key, Arrays.asList(fist, mid, last));
                codeList.add(ftof1.getMainOutAllocateOrderId()+""+ftof1.getSubOutAllocateOrderLineId()+"_"+finalNum);
            }
        });
        log.info("FullChainInventoryReportServiceImpl_getFactorySendOrder_outId_lineId={},size={}",JSONObject.toJSONString(codeList),codeList.size());
        return map;
    }

    /**
     * 电商平台总部销售调拨
     * @param wareHouseIds 仓库id
     * @param time 时间
     * @return
     */
    @FacadeInvoker
    public Map<String, List<Integer>> getFactorySalesOrder(List<String> wareHouseIds, List<String> time, Map<String, String> wareHouseIdMap) {
        // 客户:工厂直发订单数量
        Map<String, List<Integer>> map = new HashMap<>();
        // 获取计划调拨单
        List<OarsAllocateOrderDetailReportFtob> orderDetailReportFtob = getAllocateSalesOrderList(wareHouseIds, DateUtils.getFirstTime(time.get(0)), DateUtils.getLastTime(time.get(1)));

        List<String> codeList = Lists.newArrayList();
        orderDetailReportFtob.forEach(ftob -> {
            // 订单数量
            Integer quantity = StringUtils.isEmpty(ftob.getSubQuantity()) ? 0 : new BigDecimal(ftob.getSubQuantity()).intValue();
            // 发货数量
            Integer shipQuantity = StringUtils.isEmpty(ftob.getSubShipQuantity()) ? 0 : ftob.getSubShipQuantity().intValue();

            // 最终该单的调拨量
            Integer finalNum = 0;
            if (ftob.getMainReturnOrder() != 1) {
                // 正向单计算
                if (Long.valueOf(AllocateOrderStatus.CLOSED.getValue()).equals(ftob.getSubStatus())) {
                    // 仅行关闭取发货数量
                    finalNum = shipQuantity;
                } else {
                    // 如果没有 关闭 取订单数量
                    finalNum = quantity;
                }
            } else {
                /*// 退单计算
                if (Long.valueOf(AllocateOrderStatus.CLOSED.getValue()).equals(ftob.getSubStatus())) {
                    //仅行关闭取发货数量
                    finalNum = shipQuantity*-1;
                } else {
                    // 如果没有 关闭 发货数量大取发货数量，订单数量大取订单数量
                    finalNum = quantity*-1;
                }*/
                // 20220421按产品要求过滤退单数据
                return;
            }

            Date allocateOrderCreateTime = DateUtils.string2Date(DateUtils.toDateStr(ftob.getMainGmtCreate(), DateUtils.DATETIME_FORMAT), DateUtils.DATETIME_FORMAT);
            int fist = 0;
            int mid = 0;
            int last = 0;

            String mainShipAreaId = ftob.getMainShipAreaId();
            String platformId = StringUtils.isEmpty(wareHouseIdMap.get(ftob.getMainShipAreaId())) ? OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID() : wareHouseIdMap.get(ftob.getMainShipAreaId());
            String key = wareHouseIds.contains(mainShipAreaId) ? platformId : OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID();
            List<Integer> value = map.get(key);
            if (value != null) {
                fist = value.get(0);
                mid = value.get(1);
                last = value.get(2);
            }
            // 上旬
            if (DomUtil.earlyOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                fist = fist + finalNum;
            }
            // 中旬
            if (DomUtil.midOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                mid = mid + finalNum;
            }
            // 下旬
            if (DomUtil.lateOfMonth(DateUtils.formatDate(allocateOrderCreateTime))) {
                last = last + finalNum;
            }
            map.put(key, Arrays.asList(fist, mid, last));
            codeList.add(ftob.getMainOutAllocateOrderId()+""+ftob.getSubOutAllocateOrderLineId()+"_"+finalNum);
        });
        log.info("FullChainInventoryReportServiceImpl_getFactorySalesOrder_outId_lineId={},size={}",JSONObject.toJSONString(codeList),codeList.size());
        return map;
    }

    /**
     * 获取符合要求的计划调拨单
     * @param wareHouseIds
     * @return
     */
    @FacadeInvoker
    public List<OarsAllocateOrderDetailReportFtof1> getAllocateOrderList(List<String> wareHouseIds, Date startTime, Date endTime) {
        OrganizationSDO organizationSDO = allocateOrderByCode("1900021273");
        if (ObjectUtils.isEmpty(organizationSDO)) {
            return new ArrayList<>();
        }
        int limit = 500;
        QueryAllocateOrderDetailReportFtof1Request totalRequest = QueryAllocateOrderDetailReportFtof1Request.builder()
                .platformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                .mainReceiveAreaId(wareHouseIds)
                .applyOrgIds(Arrays.asList(organizationSDO.getId()))
                .type(AllocateOrderTypeEnum.PLAN.getType())
                .subStatuss(Lists.newArrayList(AllocateOrderStatus.DRAFT.getValue(),
                        AllocateOrderStatus.Shipment_Processing.getValue(),
                        AllocateOrderStatus.Part_Shipped.getValue(),
                        AllocateOrderStatus.Received.getValue(),
                        AllocateOrderStatus.Shipped.getValue(),
                        AllocateOrderStatus.Receive_Processing.getValue(),
                        AllocateOrderStatus.Part_Received.getValue(),
                        AllocateOrderStatus.WAIT_PUSH.getValue(),
                        AllocateOrderStatus.CLOSED_AND_PARTSHIPPED.getValue(),
                        AllocateOrderStatus.CLOSED_AND_PARTRECEIVED.getValue()))
                .startTime(startTime)
                .endTime(endTime)
                .start(0)
                .limit(1)
                .build();
        Result<List<OarsAllocateOrderDetailReportFtof1>> totalResult = oarsAllocateOrderDetailReportFtof1Service.queryAllocateOrderDetailReportFtof1(totalRequest);
        log.info("fullChainInventoryLoadForPage_getAllocateOrderList_request={},result_size={}", JSON.toJSONString(totalRequest),totalResult.getTotal());
        int total = totalResult.getTotal();
        int totalPage = total/limit;
        if (total%limit>0){
            totalPage++;
        }
        List<Future<List<OarsAllocateOrderDetailReportFtof1>>> futureList = Lists.newArrayList();
        for (int pageNo = 0; pageNo < totalPage; pageNo++) {
            int start = pageNo*limit;
            CompletableFuture<List<OarsAllocateOrderDetailReportFtof1>> future = CompletableFuture.supplyAsync(() -> {
                QueryAllocateOrderDetailReportFtof1Request request = QueryAllocateOrderDetailReportFtof1Request.builder()
                        .platformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                        .mainReceiveAreaId(wareHouseIds)
                        .applyOrgIds(Arrays.asList(organizationSDO.getId()))
                        .type(AllocateOrderTypeEnum.PLAN.getType())
                        .subStatuss(Lists.newArrayList(AllocateOrderStatus.DRAFT.getValue(),
                                AllocateOrderStatus.Shipment_Processing.getValue(),
                                AllocateOrderStatus.Part_Shipped.getValue(),
                                AllocateOrderStatus.Received.getValue(),
                                AllocateOrderStatus.Shipped.getValue(),
                                AllocateOrderStatus.Receive_Processing.getValue(),
                                AllocateOrderStatus.Part_Received.getValue(),
                                AllocateOrderStatus.WAIT_PUSH.getValue(),
                                AllocateOrderStatus.CLOSED_AND_PARTSHIPPED.getValue(),
                                AllocateOrderStatus.CLOSED_AND_PARTRECEIVED.getValue()))
                        .startTime(startTime)
                        .endTime(endTime)
                        .start(start)
                        .limit(limit)
                        .build();
                Result<List<OarsAllocateOrderDetailReportFtof1>> result = null;
                try {
                    result = oarsAllocateOrderDetailReportFtof1Service.queryAllocateOrderDetailReportFtof1(request);
                    if (result==null || CollectionUtils.isEmpty(result.getResult())){
                        return Lists.newArrayList();
                    }
                } catch (Exception e) {
                    log.error("多线程拉取调拨单数据异常", e);
                    return Lists.newArrayList();
                }
                return result.getResult();
            }, allocateApplyOrderTaskExecutor);
            futureList.add(future);
        }
        List<OarsAllocateOrderDetailReportFtof1> result = new ArrayList<>();
        try {
            for (Future< List<OarsAllocateOrderDetailReportFtof1>> future : futureList){
                List<OarsAllocateOrderDetailReportFtof1> subList = future.get();
                result.addAll(subList);
            }
        }catch (Exception e){
            log.error("获取多线程查询结果异常", e);
        }
        return result;
    }

    /**
     * 获取符合要求的销售调拨单
     * @param wareHouseIds
     * @return
     */
    @FacadeInvoker
    public List<OarsAllocateOrderDetailReportFtob> getAllocateSalesOrderList(List<String> wareHouseIds, Date startTime, Date endTime) {
        OrganizationSDO organizationSDO = allocateOrderByCode("1900021273");
        if (ObjectUtils.isEmpty(organizationSDO)) {
            return new ArrayList<>();
        }
        int limit = 500;
        QueryAllocateOrderDetailReportFtobRequest totalRequest = QueryAllocateOrderDetailReportFtobRequest.builder()
                .platformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                .mainShipAreaId(wareHouseIds)
                .applyOrgIds(Arrays.asList(organizationSDO.getId()))
                .type(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType())
                .warehouseTypes(Lists.newArrayList(5))
                .subStatuss(Lists.newArrayList(AllocateOrderStatus.DRAFT.getValue(),
                        AllocateOrderStatus.Shipment_Processing.getValue(),
                        AllocateOrderStatus.Part_Shipped.getValue(),
                        AllocateOrderStatus.Received.getValue(),
                        AllocateOrderStatus.Shipped.getValue(),
                        AllocateOrderStatus.Receive_Processing.getValue(),
                        AllocateOrderStatus.Part_Received.getValue(),
                        AllocateOrderStatus.WAIT_PUSH.getValue(),
                        AllocateOrderStatus.CLOSED.getValue(),
                        AllocateOrderStatus.CLOSED_AND_PARTSHIPPED.getValue(),
                        AllocateOrderStatus.CLOSED_AND_PARTRECEIVED.getValue()))
                .startTime(startTime)
                .endTime(endTime)
                .start(0)
                .limit(1)
                .build();
        Result<List<OarsAllocateOrderDetailReportFtob>> totalResult = oarsAllocateOrderDetailReportFtobService.queryAllocateOrderDetailReportFtob(totalRequest);
        log.info("fullChainInventoryLoadForPage_getAllocateSalesOrderList_request={},result_size={}", JSON.toJSONString(totalRequest),totalResult.getTotal());
        int total = totalResult.getTotal();
        int totalPage = total/limit;
        if (total%limit>0){
            totalPage++;
        }
        List<Future<List<OarsAllocateOrderDetailReportFtob>>> futureList = Lists.newArrayList();
        for (int pageNo = 0; pageNo < totalPage; pageNo++) {
            int start = pageNo*limit;
            CompletableFuture<List<OarsAllocateOrderDetailReportFtob>> future = CompletableFuture.supplyAsync(() -> {
                QueryAllocateOrderDetailReportFtobRequest request = QueryAllocateOrderDetailReportFtobRequest.builder()
                        .platformNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID())
                        .mainShipAreaId(wareHouseIds)
                        .applyOrgIds(Arrays.asList(organizationSDO.getId()))
                        .type(AllocateOrderTypeEnum.HEADQUARTER_SALES.getType())
                        .warehouseTypes(Lists.newArrayList(5))
                        .subStatuss(Lists.newArrayList(AllocateOrderStatus.DRAFT.getValue(),
                                AllocateOrderStatus.Shipment_Processing.getValue(),
                                AllocateOrderStatus.Part_Shipped.getValue(),
                                AllocateOrderStatus.Received.getValue(),
                                AllocateOrderStatus.Shipped.getValue(),
                                AllocateOrderStatus.Receive_Processing.getValue(),
                                AllocateOrderStatus.Part_Received.getValue(),
                                AllocateOrderStatus.WAIT_PUSH.getValue(),
                                AllocateOrderStatus.CLOSED.getValue(),
                                AllocateOrderStatus.CLOSED_AND_PARTSHIPPED.getValue(),
                                AllocateOrderStatus.CLOSED_AND_PARTRECEIVED.getValue()))
                        .startTime(startTime)
                        .endTime(endTime)
                        .start(start)
                        .limit(limit)
                        .build();
                Result<List<OarsAllocateOrderDetailReportFtob>> result = null;
                try {
                    result = oarsAllocateOrderDetailReportFtobService.queryAllocateOrderDetailReportFtob(request);
                    if (result==null || CollectionUtils.isEmpty(result.getResult())){
                        return Lists.newArrayList();
                    }
                } catch (Exception e) {
                    log.error("多线程拉取调拨单数据异常", e);
                    return Lists.newArrayList();
                }
                return result.getResult();
            }, allocateApplyOrderTaskExecutor);
            futureList.add(future);
        }
        List<OarsAllocateOrderDetailReportFtob> result = new ArrayList<>();
        try {
            for (Future< List<OarsAllocateOrderDetailReportFtob>> future : futureList){
                List<OarsAllocateOrderDetailReportFtob> subList = future.get();
                result.addAll(subList);
            }
        }catch (Exception e){
            log.error("获取多线程查询结果异常", e);
        }
        return result;
    }

    private Result<List<FullChainInventory>> fullChainInventoryStatLoadForPage(FullChainInventoryLoadForPageRequest request) {
        Map<String, EcInventoryStats> inventoryStatsMap = inventoryStats(request);
        if (MapUtils.isEmpty(inventoryStatsMap)) {
            return Result.listSuccess(Lists.newArrayList(), 0);
        }
        // 封装页面展示参数
        List<FullChainInventory> list = new ArrayList<>();
        for (Map.Entry<String, EcInventoryStats> entry: inventoryStatsMap.entrySet()) {
            FullChainInventory fullChainInventory = new FullChainInventory();
            EcInventoryStats stats = entry.getValue();
            fullChainInventory.setPlatformOperationName(stats.getDepartmentName());
            fullChainInventory.setPlatformId(stats.getPlatformCode());
            fullChainInventory.setPlatformName(stats.getPlatformName());
            fullChainInventory.setWarehouseQuantity(stats.getAvailableQuantity() == null ? "0" : stats.getAvailableQuantity().toString());
            fullChainInventory.setOnwayQuantity(stats.getNotArriveQuantity() == null ? "0" : stats.getNotArriveQuantity().toString());
            fullChainInventory.setMonthFirstPlan("0");
            fullChainInventory.setMonthMiddlePlan("0");
            fullChainInventory.setMonthLastPlan("0");
            list.add(fullChainInventory);
        }
        return Result.listSuccess(list, list.size());
    }

    /**
     * 获取全链路明细中的按平台汇总后的库存数据
     * @return 对应平台的汇总数据
     */
    @FacadeInvoker
    private Map<String, EcInventoryStats> inventoryStats(FullChainInventoryLoadForPageRequest fullChainInventoryRequest) {
        Map<String, EcInventoryStats> map = new HashMap<>();
        QueryByCustomerList2Request request = new QueryByCustomerList2Request();
        request.setPlatformCodeList(fullChainInventoryRequest.getPlatformCodes());
        request.setDepartmentCodeList(fullChainInventoryRequest.getDepartmentCodes());
        request.setPlatformCodeNullId(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID());
        request.setStatisticalDate(DomUtil.getToday());
        request.setStart(fullChainInventoryRequest.getStart());
        request.setLimit(fullChainInventoryRequest.getLimit());
        log.info("fullChainInventoryLoadForPage_inventoryStatsByCustomer_request={}",JSONObject.toJSONString(request));
        Result<List<EcInventoryStats>> listResult =ecInventoryStatsService.queryByCustomerList2(request);
        log.info("fullChainInventoryLoadForPage_inventoryStatsByCustomer_size={},result={}",listResult.getTotal(),JSONObject.toJSONString(listResult));
        if (ObjectUtils.isEmpty(listResult) || CollectionUtils.isEmpty(listResult.getResult())) {
            return map;
        }

        for (EcInventoryStats entry : listResult.getResult()) {
            EcInventoryStats stats = new EcInventoryStats();
            stats.setDepartmentName(entry.getDepartmentName());
            stats.setDepartmentCode(entry.getDepartmentCode());
            stats.setPlatformName(entry.getPlatformName());
            stats.setPlatformCode(entry.getPlatformCode());
            stats.setAvailableQuantity(entry.getAvailableQuantity());
            stats.setNotArriveQuantity(entry.getNotArriveQuantity());
            map.put(entry.getPlatformCode(), stats);
        }
        return map;
    }

    /**
     * 获取电商平台下的逻辑仓 key为电商平台id，value为逻辑仓的集合
     * @return
     */
    @FacadeInvoker
    private Map<String, Set<String>> getPlatformWarehouseMap(){
        SearchWarehouseForPlatformNewRequest request = new SearchWarehouseForPlatformNewRequest();
        request.setStart(0);
        request.setLimit(200);
        //request.setOrgCode("1171");
        SearchWarehouseForPlatformNewResponse response = bcOtsService.searchWarehouseForPlatformNew(request);
        if (response == null || org.apache.commons.collections.CollectionUtils.isEmpty(response.getResult())) {
            return Maps.newHashMap();
        }
        log.info("ecShareInventoryImportImpl_getEcWarehouse_request={},size={}",JSON.toJSONString(request),response.getTotal());
        List result = response.getResult();
        int totalCnt = response.getTotal();
        if (totalCnt>200) {
            int totalPage = totalCnt / 200;
            if (totalCnt % 200 > 0) {
                totalPage++;
            }
            for (int pageNo = 1; pageNo < totalPage; pageNo++) {
                request.setStart(pageNo * 200);
                response = bcOtsService.searchWarehouseForPlatformNew(request);
                if (response != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(response.getResult())) {
                    result.addAll(response.getResult());
                }
            }
        }
        //填充数据
        Map<String, Set<String>> platformWareHouseMap = new HashMap<>();
        Set<String> setFilter = Sets.newHashSet();
        for (Object o : result) {
            JSONObject json = (JSONObject) JSONObject.toJSON(o);
            // 不是电商组织的共享仓跳过
            if (2 == json.getInteger("type") && !"297930260929790508".equals(json.getString("saleOrgId"))) {
                String warehouseId = json.getString("id");
                String saleOrgId = json.getString("saleOrgId");
                setFilter.add(warehouseId + ":" + saleOrgId);
                continue;
            }
            String warehouseId = json.getString("id");
            Map<String, String> map = JSONObject.parseObject(json.getString("feature"), new TypeReference<Map<String, String>>() {
            });
            if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("ecPlatform"))){
                String platformCode = map.get("ecPlatform");
                if (CollectionUtils.isEmpty(platformWareHouseMap.get(platformCode))) {
                    Set<String> set = new HashSet<>();
                    set.add(warehouseId);
                    platformWareHouseMap.put(platformCode, set);
                } else {
                    platformWareHouseMap.get(platformCode).add(warehouseId);
                }
            } else {
                if (CollectionUtils.isEmpty(platformWareHouseMap.get(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID()))) {
                    Set<String> set = new HashSet<>();
                    set.add(warehouseId);
                    platformWareHouseMap.put(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID(), set);
                } else {
                    platformWareHouseMap.get(OtsApplicationReportSdkConstants.OTHER_PLATFORM_ID()).add(warehouseId);
                }
            }
        }
        // 过滤的非电商组织的逻辑仓
        log.info("ecShareInventoryImportImpl_getEcWarehouse_Filter={}", JSONObject.toJSONString(setFilter));
        return platformWareHouseMap;
    }

    /**
     * 通过平台id获取发货仓id集合
     * @return
     */
    private List<String> getWareHouseIdByPlatformId(List<String> platformIds, Map<String, Set<String>> warehouseMap) {
        List<String> list = Lists.newArrayList();
        platformIds.forEach(id -> {
            if (CollectionUtils.isEmpty(warehouseMap.get(id))) {
                return;
            }
            list.addAll(warehouseMap.get(id));
        });
        return list;
    }

    /**
     * 获取发货仓id、平台id映射集合
     * @return
     */
    private Map<String, String> getWareHouseIdMap(List<String> platformIds,Map<String, Set<String>> map) {
        Map<String, String> wareHouseMap = Maps.newHashMap();
        for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
            String value = entry.getKey();
            Set<String> keys = entry.getValue();
            keys.forEach(k -> {
                wareHouseMap.put(k, value);
            });
        }
        return wareHouseMap;
    }

    private FullChainInventory buildFullChainInventory(String platformId, Map<String, String> platformBySaleChannelId,
                                                       Map<String, String> platformNameByCodeMap) {
        FullChainInventory fullChainInventory = new FullChainInventory();
        fullChainInventory.setPlatformOperationName(platformBySaleChannelId.get(platformId));
        fullChainInventory.setPlatformId(platformId);
        String platformName = StringUtils.isEmpty(platformNameByCodeMap.get(platformId)) ? OtsApplicationReportSdkConstants.OTHER_PLATFORM_NAME() : platformNameByCodeMap.get(platformId);
        fullChainInventory.setPlatformName(platformName);
        return fullChainInventory;
    }

    private FullChainInventory buildFullChainInventory(FullChainInventory fullChainInventory,Map<String, EcInventoryStats> inventoryStatsMap,
                                                       Map<String, List<Long>> planMonthlyMap,FullChainInventoryLoadForPageRequest request,
                                                       Map<String, List<Integer>> factorySendOrderMap, Map<String, List<Integer>> factorySalesOrderMap) {
        String platformId = fullChainInventory.getPlatformId();
        long warehouseQuantity = 0L;
        long onwayQuantity = 0L;//调拨未到货
        if (inventoryStatsMap.get(platformId) != null) {
            warehouseQuantity = inventoryStatsMap.get(platformId) == null ? 0 : inventoryStatsMap.get(platformId).getAvailableQuantity();
            onwayQuantity = inventoryStatsMap.get(platformId) == null ? 0 : inventoryStatsMap.get(platformId).getNotArriveQuantity() * 1000;
        }
        boolean isExcel = request.getIsExcel();
        fullChainInventory.setWarehouseQuantity(DomUtil.thousandthFormat2(warehouseQuantity,isExcel));
        fullChainInventory.setOnwayQuantity(DomUtil.thousandthFormat2(onwayQuantity,isExcel));
        List<Long> planMonthlyList = org.apache.commons.collections4.CollectionUtils.isNotEmpty(planMonthlyMap.get(platformId)) ? planMonthlyMap.get(platformId):Arrays.asList(0L,0L,0L);
        List<Integer> factorySendOrderList = factorySendOrderMap.get(platformId) != null ? factorySendOrderMap.get(platformId) : Arrays.asList(0,0,0);
        List<Integer> factorySalesOrderList = factorySalesOrderMap.get(platformId) != null ? factorySalesOrderMap.get(platformId) : Arrays.asList(0, 0 , 0);
        fullChainInventory.setMonthFirstPlan(DomUtil.numFormat2(planMonthlyList.get(0) - factorySendOrderList.get(0) - factorySalesOrderList.get(0),isExcel));
        fullChainInventory.setMonthMiddlePlan(DomUtil.numFormat2(planMonthlyList.get(1) - factorySendOrderList.get(1) - factorySalesOrderList.get(1),isExcel));
        fullChainInventory.setMonthLastPlan(DomUtil.numFormat2(planMonthlyList.get(2) - factorySendOrderList.get(2) - factorySalesOrderList.get(2),isExcel));
        return fullChainInventory;
    }

}
